use common::{make_markdown_pack_parser, HtmlToMarkdownHandler};
use scraper::Html;
use html_node::YsNode;

pub mod common;
pub mod zhihu;
mod html_node;


pub fn html_to_markdown(html: &str) -> Result<String, std::io::Error> {
    let fragment = Html::parse_fragment(html);
    let root = fragment.root_element();
    let first = root.first_child().unwrap();
    let node = YsNode::new(first);
    Ok(node_to_markdown(&node))
}


fn node_to_markdown(node: &YsNode) -> String {
    let parser = make_markdown_pack_parser();
    parser.handle(node, &parser).expect("无法解析该节点")
}


#[cfg(test)]
mod tests {
    use ysbase::func::read_file;

    use super::*;
    use scraper::Html;


    // 测试完整的html
    #[test]
    fn test_full_html() {
        let html = read_file("test_resource/crates.html");
        let markdown = html_to_markdown(&html).unwrap();
        println!("{}", markdown);
    }

    // 测试列表解析器
    #[test]
    fn test_list_parser() {
        let html = "<ul><li>第一项</li><li>第二项</li></ul>";
        let markdown = html_to_markdown(html).unwrap();
        assert_eq!(markdown, "- 第一项\n- 第二项\n\n");

        let html = "<ol><li>第一项</li><li>第二项</li></ol>";
        let markdown = html_to_markdown(html).unwrap();
        assert_eq!(markdown, "1. 第一项\n2. 第二项\n\n");
    }
    

    // 测试段落解析器
    #[test]
    fn test_paragraph_parser() {
        let html = "<p>这是一个段落</p>";
        let markdown = html_to_markdown(html).unwrap();
        assert_eq!(markdown, "这是一个段落\n\n");
    }

    // 测试多种标签混合的情况
    #[test]
    fn test_multiple_tags() {
        let html = "<div><h1>这是一个标题</h1><p>这是一个段落</p><a href=\"https://www.example.com\">示例链接</a></div>";
        let markdown = html_to_markdown(html).unwrap();
        assert_eq!(markdown, "# 这是一个标题\n\n这是一个段落\n\n[示例链接](https://www.example.com)");
    }

    // 测试多种标签混合的情况
    #[test]
    fn test_multiple_tags2() {
        let html = "<div><p>这是一个\n   \n<a href=\"https://www.example.com\">示例链接</a>段落</p></div>";
        let markdown = html_to_markdown(html).unwrap();
        assert_eq!(markdown, "这是一个[示例链接](https://www.example.com)段落\n\n");
    }

    // 测试div解析器
    #[test]
    fn test_parser_div() {
        let html = "<div><h2>这是一个<a href=\"https://www.example.com\">示例链接</a>标题</h2></div>";
        let markdown = html_to_markdown(html).unwrap();
        assert_eq!(markdown, "## 这是一个[示例链接](https://www.example.com)标题\n\n");
    }

    #[test]
    fn test_parser() {
        let html = "<h2>这是一个<a href=\"https://www.example.com\">示例链接</a>标题</h2>";
        let fragment = Html::parse_fragment(html);
        let root = fragment.root_element();

        let parser = make_markdown_pack_parser();
        let node = YsNode::new(root.first_child().unwrap());
        let markdown = parser.handle(&node, &parser).unwrap();
        assert_eq!(markdown, "## 这是一个[示例链接](https://www.example.com)标题\n\n");
    }

    #[test]
    fn test_ys_element() {
        let html = "<a href=\"https://www.example.com\">示例链接</a>";
        let fragment = Html::parse_fragment(html);
        let root = fragment.root_element();
        let a_element = YsNode::new(root.first_child().unwrap());
        assert_eq!(a_element.get_tag().unwrap(), "a");

        let attrs = a_element.get_attributes();
        assert_eq!(attrs.get("href").unwrap(), "https://www.example.com");

        let children = a_element.get_children_raw();
        assert_eq!(children.len(), 1);
        let text_element = children.get(0).unwrap();
        assert_eq!(text_element.is_text_node(), true);
        assert_eq!(text_element.get_text().unwrap(), "示例链接".to_string());
    }

    #[test]
    fn test_get_children() {
        let html = "<p>这是一个<strong>特殊</strong><span>段落</span>。</p><p>这是另一个段落。</p>";
        let fragment = Html::parse_fragment(html);
        let root = fragment.root_element();
        let p0 = root.first_child().unwrap();
        let text = p0.first_child().unwrap().value().as_text().unwrap().text.to_string();
        assert_eq!(text, "这是一个");
    }

    #[test]
    fn test_basic_paragraph() {
        let html = "<p>这是一个段落</p>";
        let expected = "这是一个段落\n\n";
        assert_eq!(html_to_markdown(html).unwrap(), expected);
    }

    #[test]
    fn test_headings() {
        let html = "<h1>标题1</h1><h2>标题2</h2><h3>标题3</h3>";
        let expected = "# 标题1\n\n## 标题2\n\n### 标题3";
        assert_eq!(html_to_markdown(html).unwrap(), expected);
    }

    #[test]
    fn test_emphasis() {
        let html = "<p>这是<strong>粗体</strong>和<em>斜体</em>文本</p>";
        let expected = "这是**粗体**和*斜体*文本\n\n";
        assert_eq!(html_to_markdown(html).unwrap(), expected);
    }

    #[test]
    fn test_link() {
        let html = "<a href=\"https://www.example.com\">示例链接</a>";
        let expected = "[示例链接](https://www.example.com)";
        assert_eq!(html_to_markdown(html).unwrap(), expected);
    }

    #[test]
    fn test_complex_html() {
        let html = "<div><h1>欢迎</h1><p>这是一个<strong>重要</strong>的<a href=\"https://www.example.com\">链接</a>。</p><p>另一个段落。</p></div>";
        let expected = "# 欢迎\n\n这是一个**重要**的[链接](https://www.example.com)。\n\n另一个段落。\n\n";
        assert_eq!(html_to_markdown(html).unwrap(), expected);
    }
}
